package bp.difference.context;

import bp.da.Log;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.util.regex.Pattern;

/**
 * 自定义响应头过滤器
 * 创建安全响应包装器
 */
public class SafeHttpServletResponse extends HttpServletResponseWrapper {

    public SafeHttpServletResponse(HttpServletResponse response) {
        super(response);
    }

    @Override
    public void setHeader(String name, String value) {
        if (isValidHeaderValue(value)) {
            super.setHeader(name, sanitizeHeaderValue(value));
        } else {
            // 记录安全日志或使用安全默认值
            Log.DefaultLogWriteLineError("Attempt to set invalid header value: "+name+"="+value);
            super.setHeader(name, "secure-default");
        }
    }

    @Override
    public void addHeader(String name, String value) {
        if (isValidHeaderValue(value)) {
            super.addHeader(name, sanitizeHeaderValue(value));
        } else {
            Log.DefaultLogWriteLineError("Attempt to add invalid header value: "+name+"="+value);

            super.addHeader(name, "secure-default");
        }
    }

    @Override
    public void setDateHeader(String name, long date) {
        super.setDateHeader(name, date);
    }

    @Override
    public void setIntHeader(String name, int value) {
        super.setIntHeader(name, value);
    }


    private static final Pattern SAFE_HEADER_VALUE_PATTERN =
            Pattern.compile("^[a-zA-Z0-9\\s.,:;!?@#$%&*()_+\\-=\\[\\]{}|\\\\/~`']+$");

    private static final String[] FORBIDDEN_HEADER_PATTERNS = {
            "\r", "\n", "%0d", "%0a", "javascript:", "vbscript:",
            "expression", "url(", "onload", "onerror", "<script", "alert("
    };

    private static boolean isValidHeaderValue(String value) {
        if (value == null || value.trim().isEmpty()) {
            return false;
        }

        // 检查CRLF注入
        if (containsCRLF(value)) {
            return false;
        }

        // 检查XSS模式
        if (containsXSSPatterns(value)) {
            return false;
        }

        // 验证字符集
        return SAFE_HEADER_VALUE_PATTERN.matcher(value).matches();
    }

    private static boolean containsCRLF(String value) {
        return value.contains("\r") || value.contains("\n") ||
                value.contains("%0d") || value.contains("%0a");
    }

    private static boolean containsXSSPatterns(String value) {
        String lowerValue = value.toLowerCase();
        for (String pattern : FORBIDDEN_HEADER_PATTERNS) {
            if (lowerValue.contains(pattern)) {
                return true;
            }
        }
        return false;
    }

    private static String sanitizeHeaderValue(String value) {
        if (value == null) return "";

        // 移除CRLF字符
        String sanitized = value.replaceAll("[\\r\\n]", "");

        // 移除潜在的恶意内容
        for (String pattern : FORBIDDEN_HEADER_PATTERNS) {
            sanitized = sanitized.replaceAll("(?i)" + Pattern.quote(pattern), "");
        }

        // 限制长度
        if (sanitized.length() > 200) {
            sanitized = sanitized.substring(0, 200);
        }

        return sanitized.trim();
    }
}